package com.example.userservice.controller;

import com.example.userservice.feign.PermissionServiceClient;
import com.example.userservice.model.Result;
import com.example.userservice.model.dto.PasswordResetDTO;
import com.example.userservice.model.dto.UserLoginDTO;
import com.example.userservice.model.dto.UserPageQueryDTO;
import com.example.userservice.model.dto.UserRegisterDTO;
import com.example.userservice.model.dto.UserUpdateDTO;
import com.example.userservice.model.vo.UserVO;
import com.example.userservice.service.OperationLogService;
import com.example.userservice.service.UserService;
import com.example.userservice.common.utils.JWTUtils;
import com.example.userservice.common.constants.JWTConstants;
import com.example.userservice.common.utils.ThreadLocalUtil;
import io.jsonwebtoken.Claims;
/*import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;*/
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;

/**
 * 功能描述:
 *
 * @author Lenovo
 * @date 2025/6/15
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private PermissionServiceClient permissionServiceClient;

    @PostMapping("/register")
    public Result<Void> register(@Valid @RequestBody UserRegisterDTO userRegisterDTO, HttpServletRequest request) {
        Result<Void> result = userService.register(userRegisterDTO);

        // 记录注册操作日志 - 注册时用户ID为null，因为用户刚创建
        if (result.getCode() == 1000) { // 成功
            String detail = String.format("用户注册成功: username=%s, email=%s",
                    userRegisterDTO.getUsername(), userRegisterDTO.getEmail());
            operationLogService.sendOperationLog(null, "USER_REGISTER", detail, request);
        }
        return result;
    }

    @PostMapping("/login")
    public Result<String> login(@Valid @RequestBody UserLoginDTO userLoginDTO, HttpServletRequest request) {
        Result<String> result = userService.login(userLoginDTO);

        // 记录登录操作日志
        if (result.getCode() == 1000) { // 成功
            // 优化：从token中解析用户ID并存储到ThreadLocal（用于当前请求的日志记录）
            String token = result.getData();
            Claims claims = JWTUtils.parseToken(token, JWTConstants.SECRET);
            String userId = JWTUtils.getUserId(claims);
            // 临时设置到ThreadLocal，用于日志记录
            ThreadLocalUtil.set("userId", Long.valueOf(userId));
            String detail = String.format("用户登录成功: username=%s", userLoginDTO.getUsername());
            Long currentUserId = ThreadLocalUtil.get("userId", Long.class);
            log.info("ThreadLocal中获取到id:{}", currentUserId);
            operationLogService.sendOperationLog(currentUserId, "USER_LOGIN", detail, request);
        } else {
            String detail = String.format("用户登录失败: username=%s, reason=%s",
                    userLoginDTO.getUsername(), result.getMsg());
            operationLogService.sendOperationLog(null, "USER_LOGIN_FAILED", detail, request);
        }

        return result;
    }

    @PostMapping("/reset-password")
    public Result<Void> resetPassword(@Valid @RequestBody PasswordResetDTO passwordResetDTO, HttpServletRequest request) {
        Result<Void> result = userService.resetPassword(passwordResetDTO);
        if (result.getCode() == 1000) { // 成功
            Long userId = ThreadLocalUtil.get("userId", Long.class);
            log.info("ThreadLocal中获取到id:{}", userId);
            String detail = String.format("密码重置成功: username=%s", passwordResetDTO.getUsername());
            operationLogService.sendOperationLog(userId, "PASSWORD_RESET", detail, request);
        }

        return result;
    }

    /**
     * 获取用户列表
     * @param userPageQueryDTO
     * @param request
     * @return
     */
    @GetMapping("/users")
    public Result<List<UserVO>> getUserList(@Valid UserPageQueryDTO userPageQueryDTO, HttpServletRequest request) {
        Result<List<UserVO>> result = userService.getUserList(userPageQueryDTO);
        Long userId = ThreadLocalUtil.get("userId", Long.class);
        String detail = String.format("查询用户列表: pageNum=%d, pageSize=%d",
                userPageQueryDTO.getPageNum(), userPageQueryDTO.getPageSize());
        operationLogService.sendOperationLog(userId, "QUERY_USER_LIST", detail, request);
        log.info("ThreadLocal中获取到id:{}", userId);
        return result;
    }

    /**
     * 根据userId查询用户信息
     *
     * @param userId
     * @param request
     * @return
     */
    @GetMapping("/{userId}")
    public Result<UserVO> getUserById(@PathVariable Long userId, HttpServletRequest request) {
        Result<UserVO> result = userService.getUserDetail(userId);
        Long currentUserId = ThreadLocalUtil.get("userId", Long.class);
        String detail = String.format("查询目标用户: targetUserId=%d", userId);
        operationLogService.sendOperationLog(currentUserId, "QUERY_USER_DETAIL", detail, request);
        return result;
    }

    /**
     * 修改用户信息
     *
     * @param userId
     * @param userUpdateDTO
     * @param request
     * @return
     */
    @PutMapping("/{userId}")
    public Result<Void> updateUser(@PathVariable Long userId,
                                   @Valid @RequestBody UserUpdateDTO userUpdateDTO,
                                   HttpServletRequest request) {
        Result<Void> result = userService.updateUser(userId, userUpdateDTO);
        // 记录操作日志
        Long currentUserId = ThreadLocalUtil.get("userId", Long.class);
        if (result.getCode() == 1000) {
            String detail = String.format("修改目标用户信息成功: targetUserId=%d", userId);
            operationLogService.sendOperationLog(currentUserId, "UPDATE_USER_INFO", detail, request);
        } else {
            String detail = String.format("修改用户信息失败: targetUserId=%d, reason=%s",
                    userId, result.getMsg());
            operationLogService.sendOperationLog(currentUserId, "UPDATE_USER_INFO_FAILED", detail, request);
        }
        return result;
    }
}
